home *** CD-ROM | disk | FTP | other *** search
/ PC-Blue - MS DOS Public Domain Library / PC-Blue MS-DOS Public Domain Library - NYACC.iso / vol194 / kermasm.arc / MSXGEN.ASM < prev    next >
Encoding:
Assembly Source File  |  1985-11-14  |  13.5 KB  |  540 lines

  1. ; Generic MS DOS Kermit module
  2.  
  3.     public    serini, serrst, clrbuf, outchr, coms, vts, dodel,
  4.     public    ctlu, cmblnk, locate, lclini, prtchr, dobaud, clearl,
  5.     public    dodisk, getbaud, beep
  6.     public    count, xofsnt, puthlp, putmod, clrmod, poscur
  7.     public    sendbr, term, machnam, setktab, setkhlp, showkey
  8.     include msdefs.h
  9.  
  10. false    equ    0
  11. true    equ    1
  12. instat    equ    6
  13. rddev    equ    3fH
  14. open    equ    3dH
  15.  
  16. ; external variables used:
  17. ; drives - # of disk drives on system
  18. ; flags - global flags as per flginfo structure defined in pcdefs
  19. ; trans - global transmission parameters, trinfo struct defined in pcdefs
  20. ; portval - pointer to current portinfo structure (currently either port1
  21. ;    or port2)
  22. ; port1, port2 - portinfo structures for the corresponding ports
  23.  
  24. ; global variables defined in this module:
  25. ; xofsnt, xofrcv - tell whether we saw or sent an xoff.
  26.  
  27. datas     segment    public 'datas'
  28.     extrn    drives:byte,flags:byte, trans:byte
  29.     extrn    portval:word, port1:byte, port2:byte
  30.  
  31. machnam    db    'Generic MS-DOS 2.0$'
  32. erms20    db    cr,lf,'?Warning: System has no disk drives$' ; [21a]
  33. erms40    db    cr,lf,'?Warning: Unrecognized baud rate$'
  34. erms41    db    cr,lf,'?Warning: Cannot open com port$'
  35. erms50    db    cr,lf,'Error reading from device$'
  36. hnd1    db    cr,lf,'Enter a file handle.  Check your DOS manual if you are '
  37.     db    cr,lf,'not certain what value to supply (generally 3).$'
  38. hnd2    db    cr,lf,'Handle: $'
  39. hnderr    db    cr,lf,'Warning: Handle not known.'
  40. deverr    db    cr,lf,'Any routine using the communications port will'
  41.     db    cr,lf,'probably not work.$'
  42. hndhlp    db    cr,lf,'A four digit file handle $'
  43. dev1    db    cr,lf,'Device: $'
  44. devhlp    db    cr,lf,'Name for your systems auxiliary port $'
  45. badbd    db    cr,lf,'Unimplemented baud rate$'
  46. noimp    db    cr,lf,'Command not implemented.$'
  47. shkmsg    db    'Not implemented.'
  48. shklen    equ    $-shkmsg
  49. setktab    db    0
  50. setkhlp    db    0
  51. crlf    db      cr,lf,'$'
  52. delstr  db      BS,' ',BS,'$'         ; Delete string. [21d]
  53. clrlin  db      cr,'$'            ; Clear line (just the cr part).
  54. clreol    db    '^U',cr,lf,'$'        ; Clear line.
  55. telflg    db    0        ; non-zero if we're a terminal.
  56. xofsnt    db    0        ; Say if we sent an XOFF.
  57. xofrcv    db    0        ; Say if we received an XOFF.
  58. count    dw    0        ; Number of chars in int buffer.
  59. prthnd    dw    0        ; Port handle.
  60. prttab    dw    com2,com1
  61. com1    db    'COM1',0
  62. com2    db    'COM2',0
  63. tmp    db    ?,'$'
  64. temp    dw    0
  65. temp1   dw      ?               ; Temporary storage.
  66. temp2   dw      ?               ; Temporary storage.
  67. rdbuf    db    20 dup(?)    ; Buffer for input.
  68. prtstr    db    20 dup(?)    ; Name of auxiliary device. [27d]
  69.  
  70. ; Entries for choosing communications port. [19b]
  71. comptab    db    6        ; Number of options
  72.     mkeyw    '1',01H
  73.     mkeyw    '2',00H
  74.     mkeyw    'COM1',01H
  75.     mkeyw    'COM2',00H
  76.     mkeyw    'DEVICE',02H
  77.     mkeyw    'FILE-HANDLE',03H
  78.  
  79. ourarg    termarg    <>
  80.  
  81. datas    ends
  82.  
  83. code    segment    public
  84.     extrn    comnd:near, dopar:near, prserr:near, atoi:near, prompt:near
  85.     assume    cs:code,ds:datas
  86.  
  87. ; this is called by Kermit initialization.  It checks the
  88. ; number of disks on the system, sets the drives variable
  89. ; appropriately.  Returns normally.
  90.  
  91. DODISK    PROC    NEAR
  92.     mov ah,gcurdsk            ; Current disk value to AL.
  93.     int dos
  94.     mov dl,al            ; Put current disk in DL.
  95.     mov ah,seldsk            ; Select current disk.
  96.     int dos                ; Get number of drives in AL.
  97.     mov drives,al
  98.     ret
  99. DODISK    ENDP
  100.  
  101. ; Clear the input buffer. This throws away all the characters in the
  102. ; serial interrupt buffer.  This is particularly important when
  103. ; talking to servers, since NAKs can accumulate in the buffer.
  104. ; Do nothing since we are not interrupt driven.  Returns normally.
  105.  
  106. CLRBUF    PROC    NEAR
  107.     ret
  108. CLRBUF    ENDP
  109.  
  110. ; Clear to the end of the current line.  Returns normally.
  111.  
  112. CLEARL    PROC    NEAR
  113.     mov ah,prstr
  114.     mov dx,offset clreol
  115.     int dos
  116.     ret
  117. CLEARL    ENDP
  118.  
  119. ; Put the char in AH to the serial port.  This assumes the
  120. ; port has been initialized.  Should honor xon/xoff.  Skip returns on
  121. ; success, returns normally if the character cannot be written.
  122.  
  123. outchr:    mov bp,portval
  124.     cmp ds:[bp].floflg,0    ; Are we doing flow control.
  125.     je outch2        ; No, just continue.
  126.     xor cx,cx        ; clear counter
  127. outch1:    cmp xofrcv,true        ; Are we being held?
  128.     jne outch2        ; No - it's OK to go on.
  129.     loop outch1        ; held, try for a while
  130.     mov xofrcv,false    ; timed out, force it off and fall thru.
  131. outch2:    push dx            ; Save register.
  132.     mov al,ah        ; Parity routine works on AL.
  133.     call dopar        ; Set parity appropriately.
  134.     mov dl,al
  135.     mov ah,punout        ; Output char in DL to comm port.
  136.     int dos
  137.     pop dx
  138.     jmp rskp
  139.  
  140. ; This routine blanks the screen.  Returns normally.
  141.  
  142. CMBLNK    PROC    NEAR
  143.     mov ah,prstr
  144.     mov dx,offset crlf    ; Can't do anything else.
  145.     int dos
  146.     ret
  147. CMBLNK  ENDP
  148.  
  149. ; Homes the cursor.  Returns normally.
  150.  
  151. LOCATE  PROC    NEAR
  152.     mov dx,0        ; Go to top left corner of screen.
  153.     jmp poscur
  154. LOCATE  ENDP
  155.  
  156. ; Write a line at the bottom of the screen...
  157. ; the line is passed in dx, terminated by a $.  Returns normally.
  158. putmod    proc    near
  159.     push    dx        ; preserve message
  160.     mov    dx,1800h    ; now address line 24
  161.     call    poscur
  162.     pop    dx        ; get message back
  163.     mov    ah,prstr
  164.     int    dos        ; write it out
  165.     ret            ; and return
  166. putmod    endp
  167.  
  168. ; clear the mode line written by putmod.  Returns normally.
  169. clrmod    proc    near
  170.     mov    dx,1800h
  171.     call    poscur        ; Go to bottom row.
  172.     call    clearl        ; Clear to end of line.
  173.     ret
  174. clrmod    endp
  175.  
  176. ; Put a help message on the screen.
  177. ; Pass the message in ax, terminated by a null.  Returns normally.
  178. puthlp    proc    near
  179.     push    ax        ; preserve this
  180.     mov     ah,prstr
  181.     mov     dx,offset crlf
  182.     int     dos
  183.     pop    si        ; point to string again
  184. puthl3:    lodsb            ; get a byte
  185.     cmp    al,0        ; end of string?
  186.     je    puthl4        ; yes, stop
  187.     mov     dl,al
  188.     mov    ah,dconio
  189.     int    dos        ; else write to screen
  190.     jmp    puthl3        ; and keep going
  191. puthl4:    mov     ah,prstr
  192.     mov     dx,offset crlf
  193.     int     dos
  194.     ret
  195. puthlp    endp
  196.  
  197. ; Set the baud rate for the current port, based on the value
  198. ; in the portinfo structure.  Returns normally.
  199.  
  200. DOBAUD    PROC    NEAR
  201.     mov ah,prstr
  202.     mov dx,offset noimp    ; Say it's not implemented.
  203.     int dos
  204.     mov bx,portval
  205.     mov [bx].baud,0FFFFH    ; So it's not a recognized value.
  206.     ret            ; Must be set before starting Kermit.
  207. DOBAUD    ENDP
  208.  
  209. ; Get the current baud rate from the serial card and set it
  210. ; in the portinfo structure for the current port.  Returns normally.
  211. ; This is used during initialization.
  212.  
  213. GETBAUD    PROC    NEAR
  214.     ret            ; Can't do this.
  215. GETBAUD    ENDP
  216.  
  217. ; Use for DOS 2.0 and above.  Check the port status.  If no data, skip
  218. ; return.  Else, read in a char and return.
  219. PRTCHR    PROC    NEAR
  220.     push bx
  221.     push cx
  222.     push si
  223.     push bp
  224.     cmp prthnd,0        ; Got a handle yet? [27d]
  225.     jne prtch0        ; Yup just go on. [27d]
  226.     call opnprt        ; Else 'open' the port. [27d]
  227. prtch0:    call chkxon
  228.     mov bx,prthnd
  229.     mov al,instat
  230.     mov ah,ioctl
  231.     int dos
  232.     or al,al
  233.     jz prtch4        ; not ready...
  234.     mov bx,prthnd
  235.     mov ah,rddev
  236.     mov cx,1
  237.     mov dx,offset temp
  238.     int dos
  239.     cmp al,5        ; Error condition.
  240.     je prt3x
  241.     cmp al,6        ; Error condition
  242.     je prt3x
  243.     mov al,byte ptr temp
  244.     mov bp,portval
  245.     cmp ds:[bp].parflg,PARNON    ; no parity?
  246.     je prtch3        ; then don't strip
  247.     and al,7fh        ; else turn off parity
  248. prtch3:    pop bp
  249.     pop si
  250.     pop cx
  251.     pop bx
  252.     ret
  253. prt3x:    mov ah,prstr
  254.     mov dx,offset erms50
  255.     int dos
  256. prtch4:    pop bp
  257.     pop si
  258.     pop cx
  259.     pop bx
  260.     jmp rskp        ; no chars...
  261. PRTCHR  ENDP
  262.  
  263. ; Local routine to see if we have to transmit an xon
  264. chkxon    proc    near
  265.     push    bx
  266.     mov    bx,portval
  267.     cmp    [bx].floflg,0    ; doing flow control?
  268.     je    chkxo1        ; no, skip all this
  269.     cmp    xofsnt,false    ; have we sent an xoff?
  270.     je    chkxo1        ; no, forget it
  271.     mov    ax,[bx].flowc    ; ah gets xon
  272.     call    outchr        ; send it
  273.     nop
  274.     nop
  275.     nop            ; in case it skips
  276.     mov    xofsnt,false    ; remember we've sent the xon.
  277. chkxo1:    pop    bx        ; restore register
  278.     ret            ; and return
  279. chkxon    endp
  280.  
  281. ; Send a break out the current serial port.  Returns normally.
  282. SENDBR    PROC    NEAR
  283.     ret
  284. SENDBR    ENDP
  285.  
  286. ; Position the cursor according to contents of DX:
  287. ; DH contains row, DL contains column.  Returns normally.
  288. POSCUR    PROC    NEAR
  289.     ret
  290. POSCUR    ENDP
  291.  
  292. ; Delete a character from the terminal.  This works by printing
  293. ; backspaces and spaces.  Returns normally.
  294.  
  295. DODEL    PROC    NEAR
  296.     mov ah,prstr
  297.     mov dx,offset delstr    ; Erase weird character.
  298.     int dos            
  299.     ret
  300. DODEL    ENDP
  301.  
  302. ; Move the cursor to the left margin, then clear to end of line.
  303. ; Returns normally.
  304.  
  305. CTLU    PROC    NEAR
  306.     mov ah,prstr
  307.     mov dx,offset clrlin
  308.     int dos
  309.     call clearl
  310.     ret
  311. CTLU    ENDP
  312.  
  313. ; Set the current port.
  314.  
  315. COMS    PROC    NEAR
  316.         mov dx,offset comptab
  317.         mov bx,0
  318.         mov ah,cmkey
  319.         call comnd
  320.          jmp r
  321.         push bx
  322.         mov ah,cmcfm
  323.         call comnd              ; Get a confirm.
  324.          jmp comx        ;  Didn't get a confirm.
  325.      nop
  326.         pop bx
  327.     cmp bl,2        ; Do they want to set device name? [27d]
  328.     je coms2        ; Yes go get name. [27d]
  329.     jg coms3        ; Else pick up file handle. [27d]
  330.         mov flags.comflg,bl     ; Set the comm port flag.
  331.     cmp flags.comflg,1    ; Using Com 1?
  332.     jne coms0        ; Nope.
  333.     mov ax,offset port1
  334.     mov portval,ax
  335.     ret
  336. coms0:    mov ax,offset port2
  337.     mov portval,ax
  338.     ret
  339. comx:    pop bx
  340.     ret
  341. coms2:    mov dx,offset dev1    ; Let user supply device name.
  342.     call prompt
  343.     mov ah,cmtxt
  344.     mov bx,offset prtstr    ; Put name here
  345.     mov dx,offset devhlp
  346.     call comnd
  347.      jmp coms21        ; Did user type ^C.
  348.      nop
  349.     mov al,0        ; Need a null
  350.     mov [bx],al        ; To terminate string
  351.     mov dx,offset prtstr    ; Point to string
  352.     mov ah,open        ; Open port
  353.     mov al,2        ; For reading and writing
  354.     int dos
  355.     jnc coms22        ; Success
  356. coms21:    mov ah,prstr
  357.     mov dx,offset erms41
  358.     int dos
  359.     mov dx,offset deverr
  360.     int dos
  361.     ret
  362. coms22:    mov prthnd,ax        ; Save handle.
  363.     ret
  364. coms3:    mov dx,offset hnd2    ; Let user supply file handle.
  365.     call prompt
  366.     mov ah,cmtxt
  367.     mov bx,offset rdbuf    ; Where to put input.
  368.     mov dx,offset hndhlp    ; In case user wants help.
  369.     call comnd
  370.      jmp coms31        ; No go.
  371.      nop
  372.     cmp ah,4        ; Right amount of data?
  373.     ja coms31        ; Too many chars.
  374.     mov si,offset rdbuf
  375.     call atoi        ; Convert to real number
  376.      jmp coms31        ; Keep trying.
  377.      nop
  378.     mov prthnd,ax        ; Value returned in AX
  379.     ret
  380. coms31:    mov ah,prstr        ; Else, issue a warning.
  381.     mov dx,offset hnderr
  382.     int dos
  383.     ret            ; Yes, fail.
  384. COMS    ENDP
  385.  
  386. ; Set heath emulation on/off.
  387.  
  388. VTS    PROC    NEAR
  389.     jmp notimp
  390. VTS    ENDP
  391.  
  392. notimp:    mov ah,prstr
  393.     mov dx,offset noimp
  394.     int dos
  395.     jmp prserr
  396.  
  397. ; Initialize variables to values used by the generic MS DOS version.
  398.  
  399. lclini:    mov flags.vtflg,0    ; Don't to terminal emulation.
  400.     mov prthnd,0        ; No handle yet. [27d]
  401. ;    call opnprt        ; Get file handle for comm port.
  402.     ret
  403.  
  404. ; Get a file handle for the communications port.  Use DOS call to get the
  405. ; next available handle.  If it fails, ask user what value to use (there
  406. ; should be a predefined handle for the port, generally 3).  The open
  407. ; will fail if the system uses names other than "COM1" or "COM2".
  408. opnprt:    mov al,flags.comflg
  409.     mov ah,0
  410.     mov si,ax
  411.     shl si,1        ; double index
  412.     mov dx,prttab[si]
  413.     mov ah,open
  414.     mov al,2
  415.     int dos
  416.     jnc opnpr2
  417.     mov ah,prstr        ; It didn't like the string.
  418.     mov dx,offset erms41
  419.     int dos
  420.     mov dx,offset hnd1
  421.     int dos
  422. opnpr0:    mov dx,offset hnd2    ; Ask user to supply the handle.
  423.     call prompt
  424.     mov ah,cmtxt
  425.     mov bx,offset rdbuf    ; Where to put input.
  426.     mov dx,offset hndhlp    ; In case user wants help.
  427.     call comnd
  428.      jmp opnpr3        ; Maybe user typed a ^C.
  429.      nop
  430.     mov si,offset rdbuf
  431.     call atoi        ; Convert to real number
  432.      jmp opnpr0        ; Keep trying.
  433.      nop
  434.     mov prthnd,ax        ; Value returned in AX
  435.     ret
  436. opnpr2:    mov prthnd,ax        ; Call succeeded.
  437.     ret
  438. opnpr3:    cmp flags.cxzflg,'C'    ; Did user type a ^C?
  439.     jne opnpr4        ; No, don't say anything.
  440.     mov ah,prstr        ; Else, issue a warning.
  441.     mov dx,offset hnderr
  442.     int dos
  443. opnpr4:    ret            ; Yes, fail.
  444.  
  445. showkey:
  446.     mov ax,offset shkmsg
  447.     mov cx,shklen
  448.     ret
  449.  
  450. ; Initialization for using serial port.  Returns normally.
  451. SERINI    PROC    NEAR
  452.     cld            ; Do increments in string operations
  453.     call clrbuf        ; Clear input buffer.
  454.     ret            ; We're done.
  455. SERINI    ENDP
  456.  
  457. ; Reset the serial port.  This is the opposite of serini.  Calling
  458. ; this twice without intervening calls to serini should be harmless.
  459. ; Returns normally.
  460.  
  461. SERRST    PROC    NEAR
  462.     ret            ; All done.
  463. SERRST    ENDP
  464.  
  465. ; Produce a short beep.  The PC DOS bell is long enough to cause a loss
  466. ; of data at the port.  Returns normally.
  467.  
  468. BEEP    PROC    NEAR
  469.     mov dl,bell
  470.     mov ah,dconio
  471.     int dos
  472.     ret
  473. BEEP    ENDP
  474.  
  475. ; Dumb terminal emulator.  Doesn't work too well above 1200 baud (and
  476. ; even at 1200 baud you sometimes lose the first one or two characters
  477. ; on a line).
  478. term    proc    near
  479.     mov si,ax        ; this is source
  480.     mov di,offset ourarg    ; place to store arguments
  481.     mov ax,ds
  482.     mov es,ax        ; address destination segment
  483.     mov cx,size termarg
  484.     rep movsb        ; copy into our arg blk
  485. term1:    call prtchr
  486.     jmp short term2        ; have a char...
  487.     nop
  488.     nop
  489.     jmp short term3        ; no char, go on
  490. term2:    push ax
  491.     and al,7fh        ; mask off parity for terminal
  492.     mov dl,al
  493.     mov ah,conout
  494.     int dos            ; go print it
  495.     pop ax
  496.     test ourarg.flgs,capt    ; capturing output?
  497.     jz term3        ; no, forget it
  498.     call ourarg.captr    ; else call the routine
  499. term3:    mov ah,dconio
  500.     mov dl,0ffh
  501.     int dos
  502.     jz term1        ; no character, go on
  503.     cmp al,ourarg.escc    ; escape char?
  504.     je term4        ; yes, exit
  505.     push ax            ; save char
  506.     mov ah,al
  507.     or ah,80H        ; turn on hi bit so DOS doesn't interfere
  508.     call outchr        ; output the character
  509.     nop
  510.     nop
  511.     nop
  512.     pop ax
  513.     test ourarg.flgs,lclecho ; echoing?
  514.     jz term1        ; no, continue loop
  515.     mov dl,al
  516.     mov ah,dconio
  517.     int dos
  518.     jmp term1        ; else echo and keep going
  519. term4:    ret
  520. term    endp
  521.  
  522. ; Jumping to this location is like retskp.  It assumes the instruction
  523. ;   after the call is a jmp addr.
  524.  
  525. RSKP    PROC    NEAR
  526.     pop bp
  527.     add bp,3
  528.     push bp
  529.         ret
  530. RSKP    ENDP
  531.  
  532. ; Jumping here is the same as a ret.
  533.  
  534. R       PROC    NEAR
  535.         ret
  536. R       ENDP
  537.  
  538. code    ends
  539.     end
  540.